package la.bbs558.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import la.bbs558.dao.BbsReplyDao;
import la.bbs558.dao.UserMessageDao;
import la.bbs558.entity.UserMessage;
import la.bbs558.entity.vo.BbsReplyVO;
import la.bbs558.entity.vo.UserMessageVO;
import la.bbs558.entity.enums.SocketMessageType;
import la.bbs558.entity.enums.UserMessageType;
import la.bbs558.entity.params.SysMessagePage;
import la.bbs558.entity.params.UserMessagePage;
import la.bbs558.service.UserMessageService;
import la.bbs558.service.UserPushService;
import la.bbs558.util.Objs;
import la.bbs558.websocket.SocketMessage;
import la.bbs558.websocket.WebsocketUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 用户消息(UserMessage)表服务实现类
 *
 * @author weihanmin
 * @since 2023-12-17 16:08:08
 */
@Service("userMessageService")
public class UserMessageServiceImpl extends ServiceImpl<UserMessageDao, UserMessage> implements UserMessageService {

    @Resource
    private BbsReplyDao bbsReplyDao;

    @Resource
    private UserPushService userPushService;

    @Override
    public void sysList(SysMessagePage page) {

    }

    @Override
    public void userMessage(UserMessagePage page) {
        long userId = StpUtil.getLoginIdAsLong();
        getBaseMapper().queryMessageList(page, userId);
        List<UserMessageVO> records = page.getRecords();
        List<Long> ids = new ArrayList<>();
        for (UserMessageVO userMessageVO : records) {
            if (userMessageVO.getState() == 0) {
                ids.add(userMessageVO.getId());
            }
            Long replyReplyId = userMessageVO.getReplyReplyId();
            if (replyReplyId == null) {
                continue;
            }
            BbsReplyVO bbsReply = bbsReplyDao.selectReplyById(replyReplyId);
            userMessageVO.setReplyReplyVO(bbsReply);
        }
        if (Objs.isValid(ids)) {
            lambdaUpdate().set(UserMessage::getState, 1).in(UserMessage::getId, ids).eq(UserMessage::getState, 0).update();
        }
        this.websocketUpdateMsgCount(userId);
    }

    @Override
    public Integer messageCount() {
        return lambdaQuery()
                .eq(UserMessage::getUserId, StpUtil.getLoginIdAsLong())
                .eq(UserMessage::getState, 0)
                .count();
    }

    @Override
    public Integer messageCount(long userId) {
        return lambdaQuery()
                .eq(UserMessage::getUserId, userId)
                .eq(UserMessage::getState, 0)
                .count();
    }

    @Override
    public void websocketUpdateMsgCount(Long toUser) {
        Map<String, Object> msg = messageStatistics(toUser);
        SocketMessage socketMessage = new SocketMessage();
        socketMessage.setToUserId(toUser);
        socketMessage.setMsgType(SocketMessageType.MESSAGE.getCode());
        socketMessage.setMsgBody(JSON.toJSONString(msg));
        WebsocketUtils.sendMessageByUserId(socketMessage);
        // 发送推送消息
        userPushService.pushMessage(toUser, msg);
    }

    @Override
    public Map<String, Object> messageStatistics(Long toUser) {
        List<UserMessage> userMessages = lambdaQuery()
                .select(UserMessage::getMessageType)
                .eq(UserMessage::getUserId, toUser)
                .eq(UserMessage::getState, 0)
                .orderByDesc(UserMessage::getCreateTime)
                .list();
        //分别统计不同类型的消息数量
        Map<String, Object> msg = new HashMap<>(4);
        msg.put("total", userMessages.size());
        Integer sysCode = UserMessageType.MSG_SYS.getCode();
        Integer relayCode = UserMessageType.MSG_RELAY.getCode();
        long sysMsgCount = userMessages.stream().filter(item -> Objects.equals(item.getMessageType(), sysCode)).count();
        msg.put(sysCode.toString(), sysMsgCount);
        long replyMsgCount = userMessages.stream().filter(item -> Objects.equals(item.getMessageType(), relayCode)).count();
        msg.put(relayCode.toString(), replyMsgCount);
        if (sysMsgCount > 0) {
            msg.put("sysMsgContent", lambdaQuery().select(UserMessage::getMsgContent)
                    .eq(UserMessage::getUserId, toUser)
                    .eq(UserMessage::getMessageType, sysCode)
                    .orderByDesc(UserMessage::getCreateTime).last("limit 1").one().getMsgContent());
        } else {
            msg.put("sysMsgContent", "");
        }
        if (replyMsgCount > 0) {
            msg.put("replyMsgContent", lambdaQuery().select(UserMessage::getMsgContent)
                    .eq(UserMessage::getUserId, toUser)
                    .eq(UserMessage::getMessageType, relayCode)
                    .orderByDesc(UserMessage::getCreateTime).last("limit 1").one().getMsgContent());
        } else {
            msg.put("replyMsgContent", "");
        }
        return msg;
    }
}

